// File: jmcomic-core/src/main/java/dev/jukomu/common/postman/impl/OkHttpSessionPostman.java
package dev.jukomu.common.postman.impl;

import dev.jukomu.common.postman.AbstractSessionPostman;
import dev.jukomu.common.postman.Postman;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 对应Python的RequestsSessionPostman，基于OkHttp Session实现的Postman。
 * 请求共享同一个OkHttpClient实例（Session），自动处理Cookies。
 */
public class OkHttpSessionPostman extends AbstractSessionPostman {

    public static String POSTMAN_KEY = "okhttp-session"; // 对应Python的postman_key

    /**
     * 构造函数。
     *
     * @param kwargs 初始化参数Map。
     */
    public OkHttpSessionPostman(Map<String, Object> kwargs) {
        super(kwargs);
    }

    @Override
    protected OkHttpClient createSession(Map<String, Object> kwargs) {
        OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();

        // 处理timeout
        Number timeout = (Number) kwargs.get("timeout");
        if (timeout != null) {
            clientBuilder.connectTimeout(timeout.longValue(), TimeUnit.SECONDS)
                    .readTimeout(timeout.longValue(), TimeUnit.SECONDS)
                    .writeTimeout(timeout.longValue(), TimeUnit.SECONDS);
        }

        // 处理allow_redirects
        Boolean allowRedirects = (Boolean) kwargs.get("allow_redirects");
        if (allowRedirects != null) {
            clientBuilder.followRedirects(allowRedirects);
            clientBuilder.followSslRedirects(allowRedirects);
        }

        // 处理proxies (与OkHttpPostman相同逻辑)
        Map<String, String> proxies = (Map<String, String>) kwargs.get("proxies");
        if (proxies != null && !proxies.isEmpty()) {
            String socksAddress = proxies.get("socks");
            if (socksAddress != null && socksAddress.startsWith("socks://")) {
                String[] parts = socksAddress.substring("socks://".length()).split(":");
                if (parts.length == 2) {
                    clientBuilder.proxy(new java.net.Proxy(java.net.Proxy.Type.SOCKS, new java.net.InetSocketAddress(parts[0], Integer.parseInt(parts[1]))));
                }
            } else {
                String httpAddress = proxies.get("http");
                if (httpAddress != null && (httpAddress.startsWith("http://") || httpAddress.startsWith("https://"))) {
                    String cleanAddress = httpAddress.replaceFirst("^(http|https)://", "");
                    String[] parts = cleanAddress.split(":");
                    if (parts.length == 2) {
                        clientBuilder.proxy(new java.net.Proxy(java.net.Proxy.Type.HTTP, new java.net.InetSocketAddress(parts[0], Integer.parseInt(parts[1]))));
                    }
                }
            }
        }

        // 处理verify (SSL验证) (与OkHttpPostman相同逻辑)
        Boolean verify = (Boolean) kwargs.get("verify");
        if (verify != null && !verify) {
            clientBuilder.hostnameVerifier((hostname, session) -> true);
            try {
                TrustManager[] trustAllCerts = new TrustManager[]{
                        new X509TrustManager() {
                            @Override
                            public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                            }

                            @Override
                            public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {
                            }

                            @Override
                            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                                return new java.security.cert.X509Certificate[]{};
                            }
                        }
                };
                SSLContext sslContext = SSLContext.getInstance("SSL");
                sslContext.init(null, trustAllCerts, new SecureRandom());
                clientBuilder.sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]);
            } catch (Exception e) {
                System.err.println("Failed to disable SSL verification: " + e.getMessage());
            }
        }

        // 处理cookies：OkHttp的CookieJar是Session的核心。
        // Python的requests.sessions.cookiejar_from_dict(kwargs.pop('cookies'))
        // 这里需要将kwargs中的cookies转换为OkHttp的CookieJar
        Map<String, Object> initialCookiesMap = (Map<String, Object>) kwargs.get("cookies"); // 从kwargs中获取cookies
        if (initialCookiesMap != null && !initialCookiesMap.isEmpty()) {
            clientBuilder.cookieJar(new CookieJar() {
                private final List<Cookie> cookies = new ArrayList<>(); // 简单的内存Cookie存储

                // 初始化时将kwargs中的cookies添加到内部存储
                {
                    for (Map.Entry<String, Object> entry : initialCookiesMap.entrySet()) {
                        try {
                            // HttpUrl is required for Cookie.Builder.build(), but it's not available here.
                            // This simple CookieJar is mostly for demonstration. A proper one would manage domains.
                            // For a proper CookieJar that emulates requests.sessions.cookiejar_from_dict,
                            // you might need a more sophisticated implementation like PersistentCookieJar.
                            // For now, we just store them to be returned.
                            cookies.add(new Cookie.Builder()
                                    .name(entry.getKey())
                                    .value(String.valueOf(entry.getValue()))
                                    .domain("example.com") // Placeholder, should be the actual domain
                                    .build());
                        } catch (IllegalArgumentException e) {
                            System.err.println("Failed to build initial cookie " + entry.getKey() + ": " + e.getMessage());
                        }
                    }
                }

                @Override
                public void saveFromResponse(HttpUrl url, List<Cookie> newCookies) {
                    // This method is called when new cookies are received from a response
                    // In a real scenario, you'd add/update 'cookies' map in Postman's metaData
                    // or to a persistent store. For simplicity, just add to this session's store.
                    cookies.addAll(newCookies);
                }

                @Override
                public List<Cookie> loadForRequest(HttpUrl url) {
                    // This method is called when cookies are needed for a request
                    // You'd filter cookies based on the URL's domain/path
                    return cookies; // Return all stored cookies for simplicity
                }
            });
        } else {
            // If no initial cookies, use OkHttp's default empty CookieJar or a custom one
            clientBuilder.cookieJar(CookieJar.NO_COOKIES);
        }


        // 处理impersonate：对于OkHttp，impersonate参数会被忽略
        if (kwargs.containsKey("impersonate")) {
            System.err.println("Warning: 'impersonate' parameter is ignored by OkHttpSessionPostman as it's specific to curl_cffi.");
        }

        return clientBuilder.build();
    }

    @Override
    public Postman copy() {
        // 对于SessionPostman，复制意味着创建一个新的会话，但继承当前的metaData
        return new OkHttpSessionPostman(new HashMap<>(metaData));
    }
}